/*
 * Copyright 2012 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell.description;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.i18n.client.Constants;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.user.client.ui.*;
import finbudgettable.client.ui.grid.cell.AbstractPopupEditor;
import finbudgettable.client.ui.grid.event.ValueChangedEvent;
import finbudgettable.client.ui.grid.cell.description.toolbar.RichTextToolbar;

public class DescriptionCellEditor extends AbstractPopupEditor<String> {

    private static Resources resources;
    private final Button cancelButton;
    private final Button okButton;

    @Override
    public void setValue(String value) {
        textArea.setHTML(value);
    }

    public interface Strings extends Constants {

        @DefaultStringValue("OK")
        String ok();

        @DefaultStringValue("Отмена")
        String cancel();
    }

    interface Resources extends ClientBundle {

        interface Style extends CssResource {
            String DEFAULT_CSS = "DescriptionCellEditor.css";

            @ClassName("b-description-cell-editor__editor")
            String bDescriptionCellEditor__editor();

            @ClassName("b-description-cell-editor__cancel")
            String bDescriptionCellEditor__cancel();

            @ClassName("b-description-cell-editor__ok")
            String bDescriptionCellEditor__ok();

            @ClassName("b-description-cell-editor__toolbar")
            String bDescriptionCellEditor__toolbar();
        }

        @Source(Style.DEFAULT_CSS)
        Style style();
    }

    public static void ensureResources() {
        if (resources == null) {
            resources = GWT.create(Resources.class);
            resources.style().ensureInjected();
        }
    }

    private static final Strings strings = GWT.create(Strings.class);
    private RichTextArea textArea;

    public DescriptionCellEditor() {
        super();

        ensureResources();
        setStyleName("");

        addCloseHandler(
                new CloseHandler<PopupPanel>() {
                    @Override
                    public void onClose(CloseEvent<PopupPanel> event) {
                        if (event.isAutoClosed()) {
                            commit();
                            hide();
                        }
                    }
                }
        );

        VerticalPanel verticalPanel = new VerticalPanel();

        textArea = new RichTextArea();
        textArea.setTabIndex(0);
        textArea.addStyleName(resources.style().bDescriptionCellEditor__editor());
        textArea.addKeyDownHandler(
                new KeyDownHandler() {
                    @Override
                    public void onKeyDown(KeyDownEvent event) {
                        int keyCode = event.getNativeKeyCode();
                        if (keyCode == KeyCodes.KEY_ESCAPE) {
                            cancelButton.setFocus(true); // or grid did not get back focus
                            hide();
                        } else if (keyCode == KeyCodes.KEY_ENTER && event.isControlKeyDown()) {
                            okButton.setFocus(true); // or grid did not get back focus
                            okButton.click();
                        }
                    }
                }
        );
        VerticalPanel textAreaPanel = new VerticalPanel();
        textAreaPanel.add(textArea);

        HorizontalPanel buttonPanel = new HorizontalPanel();

        okButton = new Button(strings.ok());
        okButton.addStyleName(resources.style().bDescriptionCellEditor__ok());
        okButton.addClickHandler(
                new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        commit();
                        hide();
                    }
                });
        buttonPanel.add(okButton);

        cancelButton = new Button(strings.cancel());
        cancelButton.addStyleName(resources.style().bDescriptionCellEditor__cancel());
        cancelButton.addClickHandler(
                new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        hide();
                    }
                });
        buttonPanel.add(cancelButton);

        textAreaPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
        textAreaPanel.add(buttonPanel);

        RichTextToolbar textToolbar = new RichTextToolbar(textArea);
        SimplePanel toolBarPanel = new SimplePanel(textToolbar);
        toolBarPanel.addStyleName(resources.style().bDescriptionCellEditor__toolbar());

        verticalPanel.add(toolBarPanel);
        verticalPanel.add(textAreaPanel);

        add(verticalPanel);
    }

    private void commit() {
        this.fireEvent(new ValueChangedEvent<String>(textArea.getHTML()));
    }

    public int getTextAreaOffsetLeft() {
        return textArea.getAbsoluteLeft() - getAbsoluteLeft();
    }

    public int getTextAreaOffsetTop() {
        return textArea.getAbsoluteTop() - getAbsoluteTop();
    }

    public void setTextAreaWidth(int width) {
        textArea.setWidth(width + "px");
    }

    /**
     * Focus on the text area editor
     */
    public void focus() {
        textArea.setFocus(true);
    }

	@Override
	public void proceedSettingReadonly() {
		textArea.setEnabled(!isReadonly());
	}

}
